﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using Apache.Cassandra;
using Cassandraemon.Connection;

namespace Cassandraemon
{
	public partial class CassandraConnectionConfig
	{
		#region Default/Static/Const

		static CassandraConnectionConfig _Default = new CassandraConnectionConfig(
			new [] { "localhost" },
			9160,
			"system");

		public static CassandraConnectionConfig Default
		{
			get { return CassandraConnectionConfig._Default; }
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException();
				}
				CassandraConnectionConfig._Default = value;
			}
		}

		#endregion

		#region Constructors

		public CassandraConnectionConfig(string connectionString)
			: this(new CassandraConnectionConfigBuilder(connectionString))
		{
		}

		public CassandraConnectionConfig(string hosts, int port, string keyspace)
            : this(SplitHosts(hosts), port, keyspace)
        {
        }

		public CassandraConnectionConfig(IDictionary properties)
			: this(_Default, properties)
		{
		}

		#endregion

		#region Constructor Utilities

		static readonly char[] _HostsSeparators = { ' ' };
		static readonly string _HostsSeparator = " ";

		internal static string[] SplitHosts(string hosts)
		{
			return hosts.Split(_HostsSeparators, StringSplitOptions.RemoveEmptyEntries);
		}

		internal static string JoinHosts(string[] hosts)
		{
			return string.Join(_HostsSeparator, hosts);
		}

		#endregion

		#region NodeEnumerator

		internal ICassandraNodeEnumerator CreateNodeEnumerator(ConnectionPool pool)
		{
			var typeName = this.Node;
			if (string.IsNullOrEmpty(typeName))
			{
				return new RingNodeEnumerator(pool);
			}
			if (string.Equals(typeName, "Manual", StringComparison.InvariantCulture))
			{
				return new ManualNodeEnumerator(pool);
			}

			var type = Type.GetType(typeName);
			object instance;
			try
			{
				instance = Activator.CreateInstance(type, pool);
			}
			catch (MissingMethodException)
			{
				instance = Activator.CreateInstance(type);
			}

			var e = (ICassandraNodeEnumerator)instance;
			return e;
		}

		#endregion
	}
}
